package com.example.hctorisrael.deadolympics;

import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;

import org.andengine.audio.music.Music;
import org.andengine.audio.music.MusicFactory;
import org.andengine.audio.sound.Sound;
import org.andengine.audio.sound.SoundFactory;
import org.andengine.engine.camera.Camera;
import org.andengine.entity.primitive.Rectangle;
import org.andengine.entity.scene.background.AutoParallaxBackground;
import org.andengine.entity.scene.background.ParallaxBackground;
import org.andengine.entity.scene.background.SpriteBackground;
import org.andengine.entity.scene.menu.MenuScene;
import org.andengine.entity.scene.menu.item.IMenuItem;
import org.andengine.entity.scene.menu.item.SpriteMenuItem;
import org.andengine.entity.scene.menu.item.decorator.ScaleMenuItemDecorator;
import org.andengine.entity.sprite.AnimatedSprite;
import org.andengine.entity.sprite.ButtonSprite;
import org.andengine.entity.sprite.Sprite;
import org.andengine.input.touch.TouchEvent;
import org.andengine.opengl.texture.region.TiledTextureRegion;
import org.andengine.opengl.util.GLState;

import java.io.IOException;

/**
 * COMENTARIO NUEVO
 * La escena que muestra información del juego
 *
 */
public class EscenaJuego extends EscenaBase{
    //SONIDOS*****
    private Music musicaFondo;
    private Sound efectoExplosion;
    private Sound efectoCorrerUno;
    private Sound efectoCorrerDos;
    //Pausa
    private MenuScene escenaPausa;
    private Sprite fondoPausa;
    private Sprite spriteBtnPausa;
    private final int OPCION_CONTINUAR = 0;
    private final int OPCION_MENU = 1;
    private boolean estaEnPausa = false;
   //BARRA
    private Rectangle barra;
    private int valorBarra = 5;
    private int cont = 0;
    //Mensaje Ganaste
    private Rectangle mensaje;
    //SPRITE TIMER
    private AnimatedSprite timer;
    //CONTADOR TIEMPO
    private int tiempo = 600;
    //SPRITE MUNECO GANADOR
    private AnimatedSprite SpriteMunecoGanador;
    //SPRITE MUÑECO EXPLOTANDO
    private AnimatedSprite SpriteQuemandose;
    //SPRITE MUNECO CORRIENDO
    private AnimatedSprite SpriteMunecoCorriendo;
    //SPRITE FLECHA VOLANDO
    private AnimatedSprite SpriteFlechaVolando;
    //SPRITE HOMBRE MURIENDO1
    private AnimatedSprite SpriteHombreMuriendo1;
    //MENSAJES GANASTE / PERDISTE
    private Sprite mensajePerdiste;
    private Sprite mensajeGanaste;
    //Fondos
    private Sprite fondoBack;
    private Sprite fondoFront;
    //Marcador
    public Marcador marcador;
    public int puntaje= 600;
    //bandera que acabo el juego
    private boolean termino= false;

    @Override
    public void crearEscena() {
        crearBarra(); // Crea la barra;
        agregarTimerAnimado(); //Crea timer
        agregarFondos();
        agregarMunecoCorriendo();
        crearSonidos();
        agregarBtnPausa();
        crearEscenaPausa();
        agregarMarcador();
    };

    public void agregarMarcador() {
        marcador = new Marcador(admRecursos.engine, admRecursos.actividadJuego);
        admRecursos.camara.setHUD(marcador);
        marcador.quitarMarcadorMasAlto();
        marcador.quitarMarcadorMasAltoDos();
        marcador.quitarMarcador();
        marcador.quitarVidas();

        // Para leer las vidas actuales
        SharedPreferences preferencias = admRecursos.actividadJuego.getSharedPreferences(
                "Estado", Context.MODE_PRIVATE);
        int vidas = preferencias.getInt("vidas",marcador.getVidas());
        marcador.setVidas(vidas);

        //para leer el putnaje actual
        int puntaje = preferencias.getInt("puntaje",marcador.getMarcador());
        marcador.setMarcador(puntaje);

        //puntaj mas alto
        int ultimoMarcador = preferencias.getInt("First",marcador.getMarcadorMasAlto());
        marcador.setMarcadorMasAlto(ultimoMarcador);

        //Segundo mas alto
        int penultimoMarcador = preferencias.getInt("Second",marcador.getMarcadorMasAlto());
        marcador.setMarcadorMasAltoDos(penultimoMarcador);


    }

    private void modificarVidas() {

        // guardarlo en las preferencias
        SharedPreferences preferencias = admRecursos.actividadJuego.getSharedPreferences(
                "Estado", Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = preferencias.edit();
        editor.putInt("vidas",marcador.getVidas());
        editor.putInt("puntaje", marcador.getMarcador());
        editor.commit();


        int masAlto = marcador.getMarcadorMasAlto();
        int segundoMasAlto = marcador.getMarcadorMasAltoDos();
        int puntos = marcador.getMarcador();
        if (puntos>=masAlto) {
            editor.putInt("First",masAlto);
            editor.commit();
        }
        if(puntos>=segundoMasAlto && puntos<masAlto){
            editor.putInt("Second",segundoMasAlto);
            editor.commit();
        }
    }





    protected void onManagedUpdate(float pSecondsElapsed){
        if(estaEnPausa){
            //barra.setColor(0,1,0);
            musicaFondo.pause();
            setIgnoreUpdate(true);  // Ya no ejecuta este método
            pausar(); // Mostrar la escena de pausa
            return;
        }
        valorBarra--;

        if(cont<=0 || cont == 4) {
            puntaje --;

        }
        tiempo--;
       //Si llega a 0 la animación del timer, pierdes
        if( !timer.isAnimationRunning() && tiempo < 0){
            efectoCorrerDos.stop();
            efectoCorrerUno.stop();
            marcador.disminuirVidas(1);
            modificarVidas();
            SpriteMunecoCorriendo.stopAnimation();
            SpriteMunecoCorriendo.detachSelf();
            efectoExplosion.play();
            agregarMuñecoQuemandose();

            cont = 4;
            tiempo = 1000000;
            timer.detachSelf();

            //agregarMunecoMuriendo();
            //mensajePerdiste.setVisible(true);
        }
        //Desaparece la muñeco ganador y aparece flecha flotando
        if(cont == 1) {
            if (SpriteMunecoGanador.isAnimationRunning() == false) {
                efectoCorrerDos.stop();
                efectoCorrerUno.stop();
                SpriteMunecoGanador.detachSelf();
                SpriteMunecoGanador.dispose();
                marcador.aumentarMarcador(puntaje);
                modificarVidas();
                agregarFlechaVolando();
                cont++;
            }
        }

        if (cont == 2){
            if(SpriteFlechaVolando.isAnimationRunning() == false){
                efectoCorrerDos.stop();
                efectoCorrerUno.stop();
                SpriteFlechaVolando.detachSelf();
                agregarHombreMuriendo1();
                cont++;
            }
        }

        if(cont == 3){
            if(SpriteHombreMuriendo1.isAnimationRunning() ==false){
                efectoCorrerDos.stop();
                efectoCorrerUno.stop();
                SpriteHombreMuriendo1.detachSelf();
                SpriteHombreMuriendo1.dispose();
                siguienteEscena();
            }
        }
        barra.setHeight(valorBarra);

        if (valorBarra < 3){
            valorBarra++;
        }

        //Cuando pierdes y explota el Xtartan cambia de escena
        if( cont == 4) {
            if (!SpriteQuemandose.isAnimationRunning()) {
                efectoCorrerDos.stop();
                efectoCorrerUno.stop();
                siguienteEscena();
            }
        }
        super.onManagedUpdate(pSecondsElapsed);

    }

    //Metodo Fondos
    private void agregarFondos(){
        float xBack = admRecursos.regionFondoBack.getWidth()/2;
        float xFront = admRecursos.regionFondoFront.getWidth()/2;

        float y = ControlJuego.ALTO_CAMARA/2;
        float yFront = admRecursos.regionFondoFront.getHeight()/2;

        fondoBack = new Sprite(xBack,y,admRecursos.regionFondoBack,admRecursos.vbom);
        fondoFront = new Sprite(xFront,yFront,admRecursos.regionFondoFront,admRecursos.vbom);

        AutoParallaxBackground fondo = new AutoParallaxBackground(0,0,0,10);
        fondo.attachParallaxEntity(new ParallaxBackground.ParallaxEntity(-12,fondoBack));
        fondo.attachParallaxEntity(new ParallaxBackground.ParallaxEntity(-30,fondoFront));

        setBackground(fondo);
        setBackgroundEnabled(true);
    }

    //Método del Timer
    private void agregarTimerAnimado() {
        TiledTextureRegion regionTimer = admRecursos.regionTimer;
        timer = new AnimatedSprite(ControlJuego.ANCHO_CAMARA -45, regionTimer.getHeight()+345,
                regionTimer, admRecursos.vbom);
        // Arreglo de tiempos para los frames
        long tiempos[] = new long[11];
        for (int i = 0; i < tiempos.length; i++) {
            tiempos[i] = 1000;
        }
        //Se agrega a la escena
        timer.animate(tiempos,0,tiempos.length-1,false);
        attachChild(timer);
    }

    //Método del Hombre Muriendo 1
    private void agregarHombreMuriendo1() {
        TiledTextureRegion regionHombreMuriendo1 = admRecursos.regionHombreMuriendo1;
        SpriteHombreMuriendo1 = new AnimatedSprite(ControlJuego.ANCHO_CAMARA -80, regionHombreMuriendo1.getHeight()-100,
                regionHombreMuriendo1, admRecursos.vbom);
        // Arreglo de tiempos para los frames
        long tiempos[] = new long[34];
        for (int i = 0; i < tiempos.length; i++) {
            tiempos[i] = 40;
        }
        //Se agrega a la escena
        SpriteHombreMuriendo1.animate(tiempos, 0, tiempos.length - 1, false);
        attachChild(SpriteHombreMuriendo1);

    }

    //Método del Muneco Ganador
    private void agregarMunecoGanador() {
        TiledTextureRegion regionMunecoGanador = admRecursos.regionMunecoGanador;
        SpriteMunecoGanador = new AnimatedSprite(ControlJuego.ANCHO_CAMARA -600, regionMunecoGanador.getHeight()-200,
                regionMunecoGanador, admRecursos.vbom);

        // Arreglo de tiempos para los frames
        long tiempos[] = new long[14];

        for (int i = 0; i < tiempos.length; i++) {
            tiempos[i] = 40;

        }
        //Se agrega a la escena
        SpriteMunecoGanador.animate(tiempos, 0, tiempos.length - 1, false);
        attachChild(SpriteMunecoGanador);

    }


    //Método del Muneco Corriendo
    private void agregarMunecoCorriendo() {
        TiledTextureRegion regionMunecoCorriendo = admRecursos.regionMunecoCorriendo;
        SpriteMunecoCorriendo = new AnimatedSprite(ControlJuego.ANCHO_CAMARA -600, regionMunecoCorriendo.getHeight()-200,
                regionMunecoCorriendo, admRecursos.vbom);
        // Arreglo de tiempos para los frames
        long tiempos[] = new long[19];

        //Contador para saber cuando acabó la animación
        for (int i = 0; i < tiempos.length; i++) {
            tiempos[i] = 40;
        }
        //Se agrega a la escena
        SpriteMunecoCorriendo.animate(tiempos, 0, tiempos.length - 1, true);
        attachChild(SpriteMunecoCorriendo);
    }


    //Método de Flecha Volando
    private void agregarFlechaVolando() {
        TiledTextureRegion regionFlechaVolando = admRecursos.regionFlechaVolando;
        SpriteFlechaVolando = new AnimatedSprite(ControlJuego.ANCHO_CAMARA -300, regionFlechaVolando.getHeight()+120,
                regionFlechaVolando, admRecursos.vbom);
        // Arreglo de tiempos para los frames
        long tiempos[] = new long[5];
        for (int i = 0; i < tiempos.length; i++) {
            tiempos[i] = 400;

        }
        //Se agrega a la escena
        SpriteFlechaVolando.animate(tiempos, 0, tiempos.length - 1, false);
        attachChild(SpriteFlechaVolando);

    }

    private void agregarMensajePerdiste() {
        // Creamos el sprite de manera óptima
        mensajePerdiste = new Sprite(ControlJuego.ANCHO_CAMARA / 2, ControlJuego.ALTO_CAMARA / 2,
                admRecursos.regionPerdiste, admRecursos.vbom) {
            @Override
            protected void preDraw(GLState pGLState, Camera pCamera) {
                super.preDraw(pGLState, pCamera);
                pGLState.enableDither();
            }
        };

        attachChild(mensajePerdiste);

    }

    private void agregarMuñecoQuemandose() {
        TiledTextureRegion regionMunecoQuemandose = admRecursos.regionMunecoQuemandose;
        SpriteQuemandose = new AnimatedSprite(400, 300,
                regionMunecoQuemandose, admRecursos.vbom);

        // Arreglo de tiempos para los frames
       /* long tiempos[] = new long[8];

        for (int i = 0; i < tiempos.length; i++) {
            tiempos[i] = 60;

        }*/
        //Se agrega a la escena
        SpriteQuemandose.animate(110,false);
        attachChild(SpriteQuemandose);
        //Log.i("Muneco", "Muneco");

    }

    private void agregarMensajeGanaste() {
        // Creamos el sprite de manera óptima
        mensajeGanaste = new Sprite(ControlJuego.ANCHO_CAMARA / 2, ControlJuego.ALTO_CAMARA / 2,
                admRecursos.regionGanaste, admRecursos.vbom) {
            @Override
            protected void preDraw(GLState pGLState, Camera pCamera) {
                super.preDraw(pGLState, pCamera);
                pGLState.enableDither();
            }
        };
        attachChild(mensajeGanaste);
    }


    private void crearBarra(){
        barra = new Rectangle(15,1,80,50,admRecursos.vbom) {
            // Este método se ejecuta cada vez que se actualiza el juego (fps)
            @Override
            protected void onManagedUpdate(float pSecondsElapsed) {
                super.onManagedUpdate(pSecondsElapsed);
            }
        };

        barra.setAnchorCenter(0.5f,0.0f);
        barra.setColor(.11f,.90f,.22f,1);
        attachChild(barra);
    }


    public boolean onSceneTouchEvent(TouchEvent pSceneTouchEvent) {

        if(estaEnPausa==true){
            //setIgnoreUpdate(true);
            return super.onSceneTouchEvent(pSceneTouchEvent);
        }
        float py = barra.getY();

        if (pSceneTouchEvent.isActionDown() ) {
            valorBarra += 20;
            barra.setHeight(valorBarra);

        }
        if(barra.getHeight()> ControlJuego.ALTO_CAMARA && cont == 0){
            barra.setColor(1,0,0);
            barra.setVisible(false);
            cont++;
            agregarMunecoGanador();
            SpriteMunecoCorriendo.detachSelf();
            SpriteMunecoCorriendo.dispose();
            timer.detachSelf();
            timer.dispose();
            //siguienteEscena();

        }
            return super.onSceneTouchEvent(pSceneTouchEvent);
    }


    private void crearSonidos(){
        try {
            musicaFondo = MusicFactory.createMusicFromAsset(admRecursos.engine.getMusicManager(),
                    admRecursos.actividadJuego, "Niveles.mp3");
        }
        catch (IOException e) {
            Log.i("cargarSonidos", "No se puede cargar demo.ogg");
        }
        musicaFondo.setLooping(true);
        musicaFondo.play();
        try {
            efectoExplosion = SoundFactory.createSoundFromAsset(admRecursos.engine.getSoundManager(),
                    admRecursos.actividadJuego, "exploding.wav");
            efectoCorrerUno = SoundFactory.createSoundFromAsset(admRecursos.engine.getSoundManager(),
                    admRecursos.actividadJuego, "correrUno.WAV");
            efectoCorrerDos = SoundFactory.createSoundFromAsset(admRecursos.engine.getSoundManager(),
                    admRecursos.actividadJuego, "correrDos.WAV");
        } catch (final IOException e) {
            Log.i("cargarSonidos","No se puede cargar efecto de sonido");
        }
        efectoExplosion.setVolume(0.5f);
        efectoCorrerUno.setVolume(0.5f);
        efectoCorrerUno.setLooping(true);
        efectoCorrerUno.play();
        efectoCorrerDos.setVolume(0.5f);
        efectoCorrerDos.setLooping(true);
        efectoCorrerDos.play();

    }

    //Escena que ejecuta la pausa
    private void crearEscenaPausa(){
        escenaPausa = new MenuScene(admRecursos.camara);
        escenaPausa.setPosition(ControlJuego.ANCHO_CAMARA/2,ControlJuego.ALTO_CAMARA/2);

        //Fondo
        fondoPausa = new Sprite(ControlJuego.ANCHO_CAMARA/2,ControlJuego.ALTO_CAMARA/2,admRecursos.regionFondoPausa,admRecursos.vbom);
        SpriteBackground fondo = new SpriteBackground(0,0,0,fondoPausa);
        escenaPausa.setBackground(fondo);
        escenaPausa.setBackgroundEnabled(true);

        //Botones
        final IMenuItem opcionContinuar = new ScaleMenuItemDecorator(new SpriteMenuItem(OPCION_CONTINUAR,
                admRecursos.regionBotonContinuar,admRecursos.vbom), 1.5f, 1);
        final IMenuItem opcionMenu = new ScaleMenuItemDecorator(new SpriteMenuItem(OPCION_MENU,
                admRecursos.regionBotonMenu,admRecursos.vbom),1.5f,1);
        escenaPausa.addMenuItem(opcionContinuar);
        escenaPausa.addMenuItem(opcionMenu);
        escenaPausa.buildAnimations();
        opcionContinuar.setPosition(0,20);
        opcionMenu.setPosition(0,-70);

        escenaPausa.setOnMenuItemClickListener(new MenuScene.IOnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClicked(MenuScene pMenuScene, IMenuItem pMenuItem, float pMenuItemLocalX, float pMenuItemLocalY) {
                switch (pMenuItem.getID()) {
                    case OPCION_CONTINUAR:
                        efectoCorrerUno.play();
                        efectoCorrerDos.play();
                        escenaPausa.back(false);
                        estaEnPausa = false;
                        EscenaJuego.this.setIgnoreUpdate(false);
                        Log.i("Pausa", "Pausa");
                        break;
                    case OPCION_MENU:
                        regresarAMenu();
                        break;
                    default:
                        return false;
                }
                return true;
            }
        });
    }

    private void pausar(){
        setChildScene(escenaPausa,false,true,true);
    }

    private void agregarBtnPausa() {
        // Habilita los eventos de touch en ciertas áreas
        setTouchAreaBindingOnActionDownEnabled(true);
        spriteBtnPausa = new ButtonSprite(150,450,admRecursos.regionBtnPausa, admRecursos.vbom) {
            @Override
            public boolean onAreaTouched(TouchEvent pSceneTouchEvent, float pTouchAreaLocalX, float pTouchAreaLocalY) {
                if (pSceneTouchEvent.isActionUp()) {
                    efectoCorrerUno.pause();
                    efectoCorrerDos.pause();
                    pausar();
                }
                return super.onAreaTouched(pSceneTouchEvent, pTouchAreaLocalX, pTouchAreaLocalY);
            }
        };
        // Registra el área del botón
        registerTouchArea(spriteBtnPausa);
        attachChild(spriteBtnPausa);
    }

    // Regresar al menú principal
    private void regresarAMenu() {
        musicaFondo.stop();
        efectoExplosion.stop();
        efectoCorrerUno.stop();
        efectoCorrerDos.stop();
        admEscenas.crearEscenaMenu();
        admEscenas.setEscena(TipoEscena.ESCENA_MENU);
        admEscenas.liberarEscenaJuego();
        admRecursos.camara.setHUD(null);

    }

    private void siguienteEscena(){
        musicaFondo.stop();
        efectoExplosion.stop();
        efectoCorrerUno.stop();
        efectoCorrerDos.stop();
        admEscenas.crearEscenaEstado();
        admEscenas.setEscena(TipoEscena.ESCENA_ESTADO);
        admEscenas.liberarEscenaJuego();
        admRecursos.camara.setHUD(null);

    }

    // El usuario oprime el botón de BACK; regresar al menú principal
    @Override
    public void onBackKeyPressed() {
        if(estaEnPausa){
            escenaPausa.back();
            estaEnPausa = false;
            EscenaJuego.this.setIgnoreUpdate(false);
        }
       //regresarAMenu();
    }

    @Override
    public TipoEscena getTipoEscena() {
        return TipoEscena.ESCENA_JUEGO;
    }

    @Override
    public void liberarEscena() {
        // Liberar cada recurso usado en esta escena
        fondoBack.detachSelf();
        fondoBack.dispose();
        fondoFront.detachSelf();
        fondoFront.dispose();
        musicaFondo.release();
        barra.detachSelf();
        barra.dispose();
        admRecursos.camara.setHUD(null);
        this.detachSelf();      // La escena misma se deconecta del engine
        this.dispose();         // Libera la memoria
    }


    public Music getMusicaFondo() {
        return musicaFondo;
    }

}
